/*
 * @Author: crissu 13750782397@163.com
 * @Date: 2024-05-29 02:01:45
 * @LastEditors: crissu 13750782397@163.com
 * @LastEditTime: 2024-05-29 02:07:31
 * @FilePath: /try_concurrence/MemoryAccessSynchronization/tryPool.go
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
package memoryaccesssynchronization

import (
	"fmt"
	"sync"
)

// Manager the pool of connections, a quantity
func TryPool() {
	myPool := &sync.Pool{
		New: func() interface{} {
			fmt.Println("Creating new instance.")

			return struct{}{}
		},
	}

	// Get call New function defined in pool if there is no instance started
	myPool.Get()
	instance := myPool.Get()
	fmt.Println("instance", instance)

	// here we put a previously retrieved instance back into the pool,
	// this increases the number of instances available to one
	myPool.Put(instance)

	// when this call is executed, we will reuse the
	// previously allocated instance and put it back in the pool
	myPool.Get()

	var numCalcsCreated int
	calcPool := &sync.Pool{
		New: func() interface{} {
			fmt.Println("new calc pool")

			numCalcsCreated += 1
			mem := make([]byte, 1024)

			return &mem
		},
	}

	fmt.Println("calcPool.New", calcPool.New())

	calcPool.Put(calcPool.New())
	calcPool.Put(calcPool.New())
	calcPool.Put(calcPool.New())
	calcPool.Put(calcPool.New())

	calcPool.Get()

	const numWorkers = 1024 * 1024
	var wg sync.WaitGroup
	wg.Add(numWorkers)

	for i := numWorkers; i > 0; i-- {
		go func() {
			defer wg.Done()

			mem := calcPool.Get().(*[]byte)
			defer calcPool.Put(mem)

			// Assume something interesting, but quick is being done with
			// this memory.
		}()
	}

	wg.Wait()
	fmt.Printf("%d calculators were created.", numCalcsCreated)
}
